package com.base.cn.platform.os.service.classes.topic.reply;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.dao.classes.topic.reply.ClassesTopicReplyDao;
import com.base.cn.platform.os.entity.classes.topic.ClassesTopic;
import com.base.cn.platform.os.entity.classes.topic.reply.ClassesTopicReply;
import com.base.cn.platform.os.service.classes.topic.ClassesTopicBiz;
import com.base.cn.platform.os.service.manage.user.user.CusUserService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 班级话题回复
 *
 * @author SK
 * @since 2018-05-21
 */
@Service
public class ClassesTopicReplyBiz extends BaseBiz<ClassesTopicReply, ClassesTopicReplyDao> {

    private static final int LEAF_COUNT = 1;
    private static final int LIKE_COUNT = 2;

    @Autowired
    private ClassesTopicBiz classesTopicBiz;
    @Autowired
    private CusUserService cusUserService;


    /**
     * 查询话题评论列表
     *
     * @param classesTopicReply 话题评论查询条件
     * @param pagination        分页
     * @param setCreator        设置评论人
     * @param setLeaf           设置子评论（前N条)
     * @param setAllLeaf        设置全部子评论
     * @return 话题评论列表
     */
    public PageInfo<ClassesTopicReply> findClassesTopicReplyPage(ClassesTopicReply classesTopicReply, Pagination pagination,
                                                                 boolean setCreator, boolean setLeaf, boolean setAllLeaf, boolean isFront) {
        if (Objects.nonNull(classesTopicReply.getUser()) &&
                StringUtils.isNotEmpty(classesTopicReply.getUser().get("keyWord"))) {
            List<Map<String, Object>> cusUserList = cusUserService.queryUserList(classesTopicReply.getUser(), false, false, false, false, false, false, false);
            if (ObjectUtils.isEmpty(cusUserList)) {
                return new PageInfo<>();
            }
            String userIds = DataUtil.joining(cusUserList, (v) -> v.get("id"));
            classesTopicReply.setUserIds(userIds);
        }
        if(!isFront){
            classesTopicReply.setStatus(1);
        }
        String where = this.where(classesTopicReply);
        PageInfo<ClassesTopicReply> pageInfo = findPage(where, pagination, null);
        List<ClassesTopicReply> replyList = pageInfo.getList();
        if(isFront){
            replyList.forEach((v) -> v.setContent(v.getStatus()==2?"该条内容已被管理员删除":v.getContent()));
        }
        replyList.forEach((v) -> v.setContent(StringUtils.decodeEmoji(v.getContent())));
        this.setReplyCreator(replyList, setCreator);
        this.setReplyLeaf(replyList, setCreator, setLeaf, setAllLeaf);
        return pageInfo;
    }

    /**
     * 保存话题评论
     *
     * @param classesTopicReply 话题评论
     * @param setCreator        设置评论人
     * @return 保存结果
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> saveClassesTopicReply(ClassesTopicReply classesTopicReply,
                                                     boolean setCreator) {
        classesTopicReply.setContent(StringUtils.encodeEmoji(classesTopicReply.getContent()));
        if (DataUtil.idIsNotNull(classesTopicReply.getTargetId())) {
            ClassesTopicReply target = findById(classesTopicReply.getTargetId());
            if (target.getRootId().equals(BigDecimal.ZERO)) {
                classesTopicReply.setRootId(target.getId());
            } else {
                classesTopicReply.setRootId(target.getRootId());
            }
            save(classesTopicReply);
            // 最新五条回复评论的id
            ClassesTopicReply root = findById(classesTopicReply.getRootId());
            String[] array = root.getLeafIds().split(",");
            int end = array.length == 5 ? 4 : array.length;
            root.setLeafIds(String.join(",", Arrays.copyOfRange(array, 0, end)));
            if (array.length == 0 || (array.length == 1 && array[0].equals(""))) {
                root.setLeafIds(classesTopicReply.getId().toString());
            } else {
                root.setLeafIds(classesTopicReply.getId() + "," + root.getLeafIds());
            }
            List<ClassesTopicReply> topicReplyList = Arrays.asList(target, root);
            this.updateClassesTopicReplyStatistics(topicReplyList, LEAF_COUNT, 1);
        } else {
            classesTopicReply.setRootId(BigDecimal.ZERO);
            classesTopicReply.setTargetId(BigDecimal.ZERO);
            save(classesTopicReply);
        }
        // 更新话题评论数
        ClassesTopic classTopic = classesTopicBiz.findById(classesTopicReply.getTopicId());
        classesTopicBiz.updateClassesTopicStatistics(classTopic, ClassesTopicBiz.REPLY_NUM, 1);
        this.setReplyCreator(Collections.singletonList(classesTopicReply), setCreator);
        Map<String,Object> resultMap = ResultUtil.SUCCESS("评论成功");
        resultMap.put("replyNum",classTopic.getReplyNum().longValue() +1);
        return resultMap;
    }

    /**
     * 更新话题评论状态
     *
     * @param ids    话题评论id
     * @param status 1.正常 2.删除
     */
    public void updateClassesTopicReplyStatus(@RequestParam("ids") String ids,
                                              @RequestParam("status") Integer status) {
        ClassesTopicReply condition = new ClassesTopicReply();
        condition.setStatus(status);
        if(status == 2 ){
            //要删除的评论
            List<ClassesTopicReply> classesTopicReplies = this.find(" id in (" + ids + ")", null, null);
            ClassesTopicReply classesTopicReply = classesTopicReplies.get(0);
            BigDecimal topicId = classesTopicReply.getTopicId();
            ClassesTopic byId = classesTopicBiz.findById(topicId);
            if(byId.getReplyNum()!=0){
                long l = byId.getReplyNum() - classesTopicReplies.size();
                //更新话题总数
                ClassesTopic classesTopic = new ClassesTopic();
                if(l<0){
                    l=0;
                }
                classesTopic.setReplyNum(l);
                classesTopicBiz.updateByWhereSql(classesTopic," id ="+topicId);
            }

        }
        updateByWhereSql(condition, " id in (" + ids + ")");
    }

    /**
     * 更新班级话题统计数据
     *
     * @param topicReplyList 班级话题回复
     * @param statistics     统计
     * @param value          增加(减少)值
     */
    private void updateClassesTopicReplyStatistics(List<ClassesTopicReply> topicReplyList, int statistics, int value) {
        switch (statistics) {
            case LEAF_COUNT:
                topicReplyList.forEach((v) -> v.setLeafCount(v.getLeafCount() + value));
                break;
            case LIKE_COUNT:
                topicReplyList.forEach((v) -> v.setLikeCount(v.getLikeCount() + value));
                break;
            default:
                break;
        }
        updateBatch(topicReplyList);
    }

    /**
     * 设置评论的学员id
     *
     * @param topicReplyList 话题评论
     * @param setCreator     设置评论人
     */
    private void setReplyCreator(List<ClassesTopicReply> topicReplyList, boolean setCreator) {
        if (setCreator && ObjectUtils.isNotEmpty(topicReplyList)) {
            String cusUserIds = DataUtil.joining(topicReplyList, ClassesTopicReply::getUserId);
            Map<BigDecimal, Map<String, Object>> cusUserMap = cusUserService.queryCusUserMapByUserIds(cusUserIds, false, false, false, false, false, false, false);
            topicReplyList.forEach((v) -> v.setUser(cusUserMap.get(v.getUserId())));
        }
    }

    /**
     * 设置评论的回复
     *
     * @param topicReplyList 话题评论列表
     * @param setLeaf        设置评论的回复
     * @param setAllLeaf     设置评论的所有回复
     */
    private void setReplyLeaf(List<ClassesTopicReply> topicReplyList, boolean setCreator, boolean setLeaf, boolean setAllLeaf) {
        if ((setLeaf || setAllLeaf) && ObjectUtils.isNotEmpty(topicReplyList)) {
            List<ClassesTopicReply> target = new LinkedList<>();
            target.addAll(topicReplyList);
            if (setAllLeaf) {
                String    rootIds = DataUtil.joining(topicReplyList, ClassesTopicReply::getId);
                String where = " rootId in (" + rootIds + ")";
                List<ClassesTopicReply> leafList = find(where, null, null);
                leafList.forEach((v) -> v.setContent(v.getStatus()==2?"该条内容已被管理员删除":v.getContent()));
                leafList.forEach((v) -> v.setContent(StringUtils.decodeEmoji(v.getContent())));
                this.setReplyCreator(leafList, setCreator);
                Map<BigDecimal, List<ClassesTopicReply>> leafMap = DataUtil.grouping(leafList, ClassesTopicReply::getRootId);
                topicReplyList.forEach((v) -> {
                    v.addLeaf(leafMap.get(v.getId()));
                });
                target.addAll(leafList);
            } else {
                String leafIds = DataUtil.joining(topicReplyList, ClassesTopicReply::getLeafIds);
                if (StringUtils.isNotEmpty(leafIds)) {
                    String where = " id in (" + leafIds + ")";
                    List<ClassesTopicReply> leafList = find(where, null, null);
                    leafList.forEach((v) -> v.setContent(v.getStatus()==2?"该条内容已被管理员删除":v.getContent()));
                    leafList.forEach((v) -> v.setContent(StringUtils.decodeEmoji(v.getContent())));
                    this.setReplyCreator(leafList, setCreator);
                    Map<BigDecimal, ClassesTopicReply> leafMap = DataUtil.toMap(leafList, ClassesTopicReply::getId);
                    topicReplyList.forEach((v) -> {
                        if (StringUtils.isNotEmpty(v.getLeafIds())) {
                            String[] array = v.getLeafIds().split(",");
                            for (String leaf : array) {
                                v.addLeaf(leafMap.get(new BigDecimal(leaf)));
                            }
                        }
                    });
                    target.addAll(leafList);
                }
            }
            this.setReplyTarget(target);

        }
    }

    /**
     * 设置评论回复的目标评论
     *
     * @param topicReplyList 话题评论列表
     */
    private void setReplyTarget(List<ClassesTopicReply> topicReplyList) {

        String TargetIds = DataUtil.joining(topicReplyList, (e) -> e.getTargetId());
        String where = " id in (" + TargetIds + ") and status = 1";
        List<ClassesTopicReply> leafList = find(where, null, null);
        this.setReplyCreator(leafList, true);
        Map<BigDecimal, ClassesTopicReply> topicReplyMap = leafList.stream().distinct().collect(Collectors.toMap(e->e.getId(),e->e));
        for (ClassesTopicReply classesTopicReply: topicReplyList) {
            ClassesTopicReply reply = topicReplyMap.get(classesTopicReply.getTargetId());
            if(reply!=null){
                classesTopicReply.setTargetUser(reply.getUser());
            }
        }

    }

    private String where(ClassesTopicReply classesTopicReply) {
        String where = " 1 = 1";
        if (ObjectUtils.isNotEmpty(classesTopicReply.getStatus())) {
            where += " and status = " + classesTopicReply.getStatus();
        }
        if (DataUtil.idIsNotNull(classesTopicReply.getId())) {
            where += " and id = " + classesTopicReply.getId();
        }
        if (DataUtil.idIsNotNull(classesTopicReply.getTopicId())) {
            where += " and topicId = " + classesTopicReply.getTopicId();
        }
        if (DataUtil.isNonNegative(classesTopicReply.getRootId())) {
            where += " and rootId = " + classesTopicReply.getRootId();
        }
        if (DataUtil.idIsNotNull(classesTopicReply.getUserId())) {
            where += " and userId = " + classesTopicReply.getUserId();
        } else if (StringUtils.isNotEmpty(classesTopicReply.getUserIds())) {
            where += " and userId in ( " + classesTopicReply.getUserIds() + ")";
        }
        where+= "  ORDER BY createTime desc";
        return where;
    }
}
